<!--
 * Tencent is pleased to support the open source community by making BK-JOB生物智算平台 available.
 *
 * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
 *
 * BK-JOB生物智算平台 is licensed under the MIT License.
 *
 * License for BK-JOB生物智算平台:
 *
 *
 * Terms of the MIT License:
 * ---------------------------------------------------
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
 * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
 * the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
-->

<template>
  <div v-bkloading="{ isLoading }" class="server-file-edit-box">
    <table>
      <thead>
        <th>{{ $t('文件路径') }}</th>
        <th>{{ $t('服务器列表') }}</th>
        <th>{{ $t('Agent 状态') }}</th>
        <th>{{ $t('服务器账号') }}</th>
        <th>{{ $t('操作') }}</th>
      </thead>
      <tbody>
        <tr v-for="(row, index) in serverFileList" :key="index">
          <td>
            <edit-file-path :value="row.fileLocation" @on-change="value => handleFilePathEdit(value, index)" />
          </td>
          <td>
            <!-- 编辑主机变量 -->
            <div v-if="row.isVar" class="global-variable-render-box" :class="{ 'value-error': !row.host.variable }"
              style="margin-left: -10px;">
              <bk-select class="variable-edit-select" :clearable="false" searchable :value="row.host.variable"
                @change="value => handleVariableChange(value, index)">
                <bk-option v-for="(option, variableIndex) in variable" :id="option.name" :key="variableIndex"
                  :name="option.name" />
              </bk-select>
              <icon v-if="!row.host.variable" v-bk-tooltips="$t('全局变量被删除，重新设置')" class="error-tips" type="info" />
            </div>
            <!-- 手动添加主机 -->
            <div v-else class="server-edit-btn" @click="handleHostEdit(index)" v-html="row.serverDesc" />
          </td>
          <td>
            <!-- 展示服务器列表主机信息 -->
            <render-server-agent v-if="!row.isVar" key="host" :host-node-info="row.host.hostNodeInfo"
              :separator="agentSeparator" :title="`${$t('服务器文件-服务器列表')}`" />
            <!-- 展示变量的主机信息 -->
            <render-server-agent v-else :key="row.serverDesc" :host-node-info="findVariableValue(row.serverDesc)"
              :separator="agentSeparator" :title="`${$t('全局变量')} - ${row.host.variable}`" />
          </td>
          <td>
            <account-select class="account-add-btn" type="system" :value="row.account"
              @change="value => handleAccountChange(value, index)" />
          </td>
          <td>
            <bk-button text @click="handlerRemove(index)">
              {{ $t('移除') }}
            </bk-button>
          </td>
        </tr>
      </tbody>
      <component :is="addCom" key="add" v-bind="$attrs" :account="accountList" :data="serverFileList"
        :variable="variable" @on-cancel="handleAddCancel" @on-change="handleAddSave" />
    </table>
    <ip-selector :show-dialog="isShowChooseIp" :value="currentHost" @change="handleHostChange"
      @close-dialog="handleCloseIpSelector" />
  </div>
</template>
<script>
import { mapMutations } from 'vuex';

import AccountManageService from '@service/account-manage';

import TaskHostNodeModel from '@model/task-host-node';

import AccountSelect from '@components/account-select';
import RenderServerAgent from '@components/render-server-agent';

import EditFilePath from '../../components/edit-file-path';

import AddHostAndVariable from './host-and-variable';
import AddOnlyHost from './only-host';

export default {
  name: 'SourceFileServer',
  components: {
    RenderServerAgent,
    AccountSelect,
    AddOnlyHost,
    AddHostAndVariable,
    EditFilePath,
  },
  inheritAttrs: false,
  props: {
    data: {
      type: Array,
      required: true,
    },
    mode: {
      type: String,
      default: '',
    },
    variable: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      isLoading: true,
      serverFileList: [],
      currentHost: {},
      accountList: [],
      isShowChooseIp: false,
      currentIndex: 0,
    };
  },
  computed: {
    addCom() {
      if (this.isLoading) {
        return 'div';
      }
      if (this.mode === 'onlyHost') {
        return AddOnlyHost;
      }
      return AddHostAndVariable;
    },
    agentSeparator() {
      if (this.mode === 'onlyHost') {
        return '、';
      }
      return '\n';
    },
  },
  watch: {
    data: {
      handler(newData) {
        if (this.innerChange) {
          this.innerChange = false;
          return;
        }
        this.serverFileList = newData;
      },
      immediate: true,
    },
  },
  created() {
    this.fetchAccount();
    this.editNewSourceFile(false);
  },
  methods: {
    ...mapMutations('distroFile', [
      'editNewSourceFile',
    ]),
    /**
     * @desc 获取系统账号列表
     */
    fetchAccount() {
      AccountManageService.fetchAccountWhole({
        category: 1,
      }).then((data) => {
        this.accountList = data;
      })
        .finally(() => {
          this.isLoading = false;
        });
    },
    /**
     * @desc 从全局变量列表中查找指定全局变量的值
     * @param {String} variableName 全局变量名
     */
    findVariableValue(variableName) {
      const curVariable = this.variable.find(item => item.name === variableName);
      if (!curVariable) {
        const {
          hostNodeInfo,
        } = new TaskHostNodeModel({});
        return hostNodeInfo;
      }
      return curVariable.defaultTargetValue.hostNodeInfo;
    },
    /**
     * @desc 服务器文件更新
     */
    triggerChange() {
      this.innerChange = true;
      this.$emit('on-change', [
        ...this.serverFileList,
      ]);
    },
    /**
     * @desc 编辑服务器文件的路径
     * @param {Array} fileLocation 服务器文件
     * @param {Number} index 编辑中的服务器文件的索引
     */
    handleFilePathEdit(fileLocation, index) {
      this.serverFileList[index].fileLocation = fileLocation;
      this.triggerChange();
    },
    /**
     * @desc 开始编辑服务器文件的主机——显示ip选择器弹框
     * @param {Number} index 编辑中的服务器文件的索引
     */
    handleHostEdit(index) {
      this.isShowChooseIp = true;
      this.currentIndex = index;
      this.currentHost = this.data[index].host.hostNodeInfo;
    },
    handleCloseIpSelector() {
      this.isShowChooseIp = false;
    },
    /**
     * @desc 更新编辑服务器文件的主机
     * @param {Object} hostNodeInfo 服务器主机信息
     */
    handleHostChange(hostNodeInfo) {
      this.serverFileList[this.currentIndex].host.hostNodeInfo = hostNodeInfo;
      this.triggerChange();
    },
    /**
     * @desc 更新编辑服务器文件的全局变量
     * @param {Array} variable 服务器主机信息
     * @param {Number} index 编辑中的服务器文件的索引
     */
    handleVariableChange(variable, index) {
      this.serverFileList[index].host.variable = variable;
      this.triggerChange();
    },
    /**
     * @desc 开始编辑服务器文件的服务器账号
     * @param {Number} index 编辑中的服务器文件的索引
     */
    handleEditAccount(index) {
      this.serverFileList[index].isEditAccount = true;
      this.editAccountIndex = index;
      this.triggerChange();
    },
    /**
     * @desc 更新编辑服务器文件的服务器账号
     * @param {Number} account 服务器账号id
     * @param {Number} index 编辑中的服务器文件的索引
     */
    handleAccountChange(account, index) {
      const serverFile = this.serverFileList[index];
      serverFile.account = account;
      this.triggerChange();
    },
    /**
     * @desc 删除指定的服务器文件
     * @param {Number} index 服务器文件的索引
     */
    handlerRemove(index) {
      this.serverFileList.splice(index, 1);
      this.triggerChange();
    },
    /**
     * @desc 添加一条服务器文件
     * @param {Object} serverFile 服务器文件
     */
    handleAddSave(serverFile) {
      this.serverFileList.push(serverFile);
      this.triggerChange();
    },
    /**
     * @desc 取消添加一条服务器文件
     */
    handleAddCancel() {
      if (this.serverFileList.length < 1) {
        this.$emit('on-close');
      }
    },
  },
};
</script>
<style lang='postcss'>
.server-file-edit-box {
  .global-variable-render-box {
    position: relative;
    border: 1px solid transparent;
    border-radius: 2px;

    &.value-error {
      border-color: #ea3636;
    }

    .error-tips {
      position: absolute;
      top: 0;
      right: 0;
      z-index: 1999;
      display: flex;
      height: 30px;
      padding: 0 6px;
      font-size: 16px;
      color: #ea3636;
      cursor: pointer;
      align-items: center;
    }
  }

  .variable-edit-select,
  .account-add-btn {

    &:hover,
    &.is-focus {
      .bk-select-angle {
        display: block;
      }
    }

    .bk-select-angle {
      display: none;
      font-size: 20px;
    }
  }

  .account-add-btn,
  .server-edit-btn,
  .server-add-only-host-btn {
    margin-left: -10px;
  }

  .server-add-btn,
  .server-edit-btn,
  .server-add-host {
    cursor: pointer;
    border-radius: 2px;

    &:hover {
      background: #f0f1f5;
    }
  }

  .server-add-btn,
  .server-add-host {
    height: 30px;
    line-height: 30px;
  }

  .server-edit-btn {
    min-height: 30px;
    padding: 5px 10px;
    line-height: 20px;
  }

  .server-add-btn {
    display: flex;
    height: 30px;
    margin-left: -10px;
    font-size: 12px;
    cursor: pointer;
    background: #f7f8fa;
    border-radius: 2px;
    align-items: center;

    .server-type-select {
      flex: 0 0 auto;
    }

    .line {
      height: 16px;
      background: #dcdee5;
      flex: 0 0 1px;
    }

    .server-add-variable {
      flex: 1;
    }

    .server-add-host {
      display: flex;
      height: 30px;
      font-size: 12px;
      border-radius: 2px;
      flex: 1;
      align-items: center;
      justify-content: center;
    }
  }

  .server-add-only-host-btn {
    display: flex;
    height: 30px;
    padding: 0 10px;
    font-size: 12px;
    cursor: pointer;
    background: #f7f8fa;
    border-radius: 2px;
    align-items: center;
    justify-content: center;

    &:hover {
      color: #979ba5;
      background: #f0f1f5;
    }

    .add-flag {
      margin-right: 6px;
      margin-bottom: 2px;
    }
  }

  .create-server-file {
    tr {
      td {
        border-top: 1px solid #dcdee5;
      }
    }
  }

  .bk-select {
    height: 30px;
    line-height: 30px;
    border: none;

    &:hover {
      background: #f0f1f5;
    }

    .bk-select-name {
      height: 30px;
      padding-right: 16px;
      padding-left: 10px;
      line-height: 30px;
    }
  }
}
</style>
